package auction

import org.openqa.selenium.htmlunit.HtmlUnitDriver
import geb.Browser
import groovyx.gpars.GParsPool
import java.text.NumberFormat

import java.math.RoundingMode
import used.UsedCar

class CarInfoService {

	static transactional = true

	def scrapeAutoTrader() {

		def carsToModels = ["BMW": "325",
				"HONDA": "ACCORD",
				"HYUNDAI": "ACCENT"]

		def cars = []
		GParsPool.withPool(3) {
			carsToModels.eachParallel { type, model ->
				def driver = new HtmlUnitDriver()

				try {
					def browser = new Browser(driver)
					def url = "http://www.autotrader.co.uk/search/used/cars/$type/$model/postcode/w23qh/radius/100/fuel-type/petrol/maximum-age/up_to_5_years_old/sort/priceasc"
					browser.go(url)

					def numberOfPages = browser.$(".sortAndPaginate .totalPages").text() as int

					2.times { pageNumber ->
						url = "http://www.autotrader.co.uk/search/used/cars/$type/$model/postcode/w23qh/radius/100/fuel-type/petrol/maximum-age/up_to_5_years_old/sort/priceasc/page/$pageNumber"
						browser.go(url)

						// get all the cars
						def searchResults = browser.$(".searchResult")
						searchResults.each {

							def id = parseNumber(it.@id)
							def price = parsePrice(it.find(".offerPrice").text())
							def title = it.find("a.title").text()
							def mileage = parseNumber(it.find("span.mileage").text())
							def transmission = it.find("span.transmission").text()
							def engine = it.find("span.engine").text()
							def fuel = it.find("span.fuel").text()
							def year = parseNumber(it.find(".advertIconsPrice h3").text())
							cars << new ParsedCar(
									id: id,
									price: price,
									title: title,
									mileage: mileage,
									transmission: transmission,
									engine: engine,
									fuel: fuel,
									year: year
							)

						}
					}
				} finally {
					driver.quit()
				}
			}

		}
		println "number of cars is ${cars.size()}"
	}

	void filterListOfCars(Collection<ParsedCar> cars){
		/*Need to switch this to something else*/
		def carsInDb = UsedCar.list()

		def carsNotInDb = []
		def carsToBeUpdated = [:]
		GParsPool.withPool(3) {
			cars.eachParallel {ParsedCar car ->
				carsInDb.any{db-> db.websiteId == car.id} ? carsToBeUpdated[car.id] = car : carsNotInDb << car
			}
		}
		//now update db
		GParsPool.withPool(3) {
			carsToBeUpdated.eachParallel{ id, ParsedCar parsedCar ->
				def car = UsedCar.findByWebsiteId( id )
				car.price = parsedCar.price
				car.save()
			}
		}
		GParsPool.withPool(3) {
			carsNotInDb.eachParallel{ ParsedCar car ->
				UsedCar usedCar = UsedCar.createCar( car)
				usedCar.save()
			}
		}

	}


	BigDecimal parsePrice(String price){
		return parse(price, BigDecimal).setScale(2, RoundingMode.HALF_EVEN)
	}

	Long parseNumber(String milage){
		return parse(milage, Long)
	}

	def parse(String element, Class clazz){
		def finder = element =~ /\d.*$/
		def number = NumberFormat.getInstance().parse(finder.find() ? finder[0] : '0')
		return clazz.newInstance( number)
	}

}
